from typing import Callable, TypeVar, Generic, List
from typing_extensions import TypeGuard


class Tes(object):

    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __add__(self, other: 'Tes') -> 'Tes':
        return Tes(self.a + other.a, self.b + other.b)

    def __str__(self):
        return str({'a': self.a, 'b': self.b})

    def __iadd__(self, other: 'Tes') -> 'Tes':
        self.a += other.a
        self.b += other.b
        return self


T = TypeVar('T', bound=Callable)

class Delegate(Generic[T]):
    def __init__(self):
        self.func: List[T] = []
        self._func_ids = []

    def __add__(self, other: T) -> 'Delegate[T]':
        if id(other) in self._func_ids:
            return self
        self._func_ids.append(id(other))
        self.func.append(other)
        return self

    def __iadd__(self, other: T) -> 'Delegate[T]':
        """增加多次不会产生变化"""
        # if not callable(other):
        #     raise ValueError('必须是可调用对象')
        if id(other) in self._func_ids:
            return self
        self._func_ids.append(id(other))
        self.func.append(other)
        return self

    def __isub__(self, other: T) -> 'Delegate[T]':
        if id(other) not in self._func_ids:
            return self
        self._func_ids.remove(id(other))
        self.func.remove(other)
        return self

    def __call__(self, *args, **kwargs):
        for f in self.func:
            f(*args, **kwargs)


def add1(a, b):
    print('add1', a + b)


def add2(a, b):
    print('add2', a + 2 * b)


class ADD3:
    def add(self, a, b):
        print('add3', a + 3 * b)



if __name__ == '__main__':
    d = Delegate[Callable[[int, int], int]]()
    d += add1
    d += add2

    d(3, 3)

    d -= add1
    d(3,3)

    d += ADD3().add
    print('xxxxxxxxx')
    d(4, 5)

    # d += 3.1
    # d.__iadd__(3)
